package com.um.springboot.starter.orm.service;

import com.um.springboot.starter.entity.Page;
import com.um.springboot.starter.orm.entity.RangeEntity;
import com.um.springboot.starter.orm.params.ExportParams;

import java.util.List;
import java.util.Map;

/**
 * @author 邓南辉
 * 日期 2022/9/9
 * 版权所有 广州优匠科技有限公司
 */
public interface BaseEntityService<T>{

    /**
     * 生成主键ID
     * @return
     */
    String createUUIDPrimaryId();

    /**
     * 获得租户ID
     * @return
     */
    String getComId();

    /**
     * 添加记录，饶开框架，不做历史记录
     */
    boolean saveRecord(T entity);

    /**
     * 保存实体,饶开框架，不添加com_id
     */
    boolean saveRow(T entity);

    /**
     * 插入一个实体,饶开框架，不添加com_id
     * @param entity
     * @return
     */
    boolean addRow(T entity);

    /**
     * 更新一个实体,饶开框架，不添加com_id
     * @param entity
     * @return
     */
    boolean updateRow(T entity);

    /**
     * 按主键删除实体，饶开框架，不添加com_id
     * @param id
     * @return
     */
    boolean deleteRow(String id);

    /**
     * 根据单个属性删除实体，饶开框架，不添加com_id
     * @param property
     * @param value
     * @return
     */
    boolean deleteRow(String property,Object value);

    /**
     * 根据多个属生查询实体，饶开框架，不添加com_id
     * @param properties
     * @param values
     * @return
     */
    boolean deleteRow(String[] properties,Object[] values);

    /**
     * 根据主键查询实体，饶开框架，不添加com_id
     * @param id
     * @return
     */
    T getRow(String id);
    /**
     * 根据单个属性查询实体，饶开框架，不添加com_id
     * @param property
     * @param value
     * @return
     */
    T getRow(String property,Object value);

    /**
     * 根据多个属生查询实体，饶开框架，不添加com_id
     * @param properties
     * @param values
     * @return
     */
    T getRow(String[] properties,Object[] values);

    /**
     * 根据单个属性查询列表，饶开框架，不添加com_id
     * @param property
     * @param value
     * @return
     */
    List<T> getRows(String property,Object value);

    /**
     * 根据多个属生查询列表，饶开框架，不添加com_id
     * @param property
     * @param value
     * @return
     */
    List<T> getRows(String property,Object value,String orderName,String sortNo);

    /**
     * 根据多个属生查询列表，饶开框架，不添加com_id
     * @param properties
     * @param values
     * @return
     */
    List<T> getRows(String[] properties,Object[] values);

    /**
     * 根据多个属生查询列表，饶开框架，不添加com_id
     * @param properties
     * @param values
     * @return
     */
    List<T> getRows(String[] properties,Object[] values,String orderName,String sortNo);

    /**
     * 插入一条数据，并返回自增ID
     *
     * @param entity 属性和值
     * @return 执行成功返回true
     */
    Long insert(T entity);

    /**
     * 保存一个对象,如果对象存在就更新，不存在就插入
     *
     * @param entity 属性和值
     * @return 执行成功返回true
     */
    boolean save(T entity);

    /**
     * 保存一个对象,如果对象存在就更新，不存在就插入
     *
     * @param entity 属性和值
     * @return 返回保存后的实体Map
     */
    T saveEntity(T entity);

    /**
     * 保存多个对象列表
     *
     * @param list 对象列表
     */
    boolean saveList(List<T> list);

    /**
     * 插入一个对象
     *
     * @param entity 属性和值
     * @return 返回保存后的实体Map
     */
    boolean add(T entity);

    /**
     * 插入一个对象,不生成新的主键ID
     *
     * @param entity 属性和值
     * @return 返回保存后的实体Map
     */
    boolean add(T entity,boolean autoCreateId);

    /**
     * 更改一个对象
     *
     * @param entity 实体Map
     */
    boolean update(T entity);

    /**
     * 插入一个对象
     *
     * @param entity 属性和值
     * @return 返回保存后的实体Map
     */
    T addEntity(T entity);

    /**
     * 更改一个对象
     *
     * @param entity 实体Map
     */
    T updateEntity(T entity);

    /**
     * 更新一个对象，可以设置更新空值
     * @param entity
     * @param updateNullProperties
     * @return
     */
    T updateEntity(T entity,String[] updateNullProperties);

    /**
     * 删除一个列表
     *
     * @param list 实体列表
     * @return 执行成功返回true
     */
    boolean delete(List<T> list);

    /**
     * 根据实体
     *
     * @param entity
     * @return 执行成功返回true
     */
    boolean delete(T entity);

    /**
     * 删除一个实体
     * @param id
     * @return
     */
    boolean delete(String id);

    /**
     * 根据一个属性删除对象
     *
     * @param property  属性名
     * @param value     值
     * @return 执行成功返回true
     */
    boolean delete(String property, Object value);

    /**
     * 物量删除一个实体
     * @param property 属性名
     * @param value 属性值
     * @return
     */
    boolean deleteTrue(String property,Object value);

    /**
     * 物量删除一个实体
     * @param properties 属性名
     * @param values 属性值
     * @return
     */
    boolean deleteTrue(String[] properties, Object[] values);

    /**
     * 根据指定属性删除对象
     *
     * @param properties 属性数组
     * @param values     值数组
     * @return 执行成功返回true
     */
    boolean delete(String[] properties, Object[] values);

    /**
     * 根据id列表删除对象
     *
     * @param ids     值数组
     * @return 执行成功返回true
     */
    boolean deleteIds(List<String> ids);


    /**
     * 查询一个对象
     * @param properties 查询属性数组
     * @param values 查询属性值数组
     * @return 返回一个对象
     */
    T getEntity(String[] properties, Object[] values);

    /**
     * 查询一个对象
     * @param property 查询属性
     * @param value 查询属性值
     * @return 返回一个对象
     */
    T getEntity(String property, Object value);

    /**
     * 根据主键ID查询一个对象
     * @param id 主键ID
     * @return 返回一个对象
     */
    T getEntity(String id);

    /**
     * 查询一个对象，忽略逻辑删除
     * @param properties 查询属性数组
     * @param values 查询属性值数组
     * @return 返回一个对象
     */
    T getRealEntity(String[] properties, Object[] values);

    /**
     * 查询一个对象，忽略逻辑删除
     * @param property 查询属性
     * @param value 查询属性值
     * @return 返回一个对象
     */
    T getRealEntity(String property, Object value);

    /**
     * 根据主键ID查询一个对象，忽略逻辑删除
     * @param id 主键ID
     * @return 返回一个对象
     */
    T getRealEntity(String id);

    /**
     * 根据自定义sql名称查询实体
     * @param sqlName sql名称
     * @param values 参数值
     * @return
     */
    T getEntityBySqlName(String sqlName,Object... values);

    /**
     * 根据自定义sql名称查询列表
     *
     * @param sqlName sql名称
     * @param clazz
     * @param values  参数值
     * @return
     */
    <M> M getViewModel(String sqlName, Class<M> clazz, Object[] values);

    /**
     * 根据自定义sql查询列表
     *
     * @param sql sql
     * @param clazz
     * @param values  参数值
     * @return
     */
    <M> M getViewModelBySQL(String sql, Class<M> clazz, Object[] values);


    /**
     * 查询所有列表
     *
     * @return
     */
    List<T> getAll();

    /**
     * 根据单一属性查询列表
     *
     * @param property 属性
     * @param value    值
     * @return
     */
    List<T> getList(String property, Object value);

    /**
     * 根据单一属性查询列表，并指定单个排序条件
     *
     * @param property  属性
     * @param value     值
     * @param orderName 排序属性
     * @param sortOn    降序或升序
     * @return
     */
    List<T> getList(String property, Object value, String orderName, String sortOn);

    /**
     * 根据多个属性查询指定列表
     *
     * @param properties 属性名称
     * @param values     属性值
     * @return 返回一个列表
     */
    List<T> getList(String[] properties, Object[] values);

    /**
     * 根据多个属性查询指定列表
     *
     * @param properties 属性名称
     * @param values     属性值
     * @param orderNames 排序字段数组
     * @param sortOns    降序或升序数组
     * @return 返回一个列表
     */
    List<T> getList(String[] properties, Object[] values, String[] orderNames, String[] sortOns);

    /**
     * 根据单一属性查询列表
     *
     * @param property 属性
     * @param value    值
     * @return
     */
    List<T> getListByLike(String property, Object value);

    /**
     * 根据单一属性查询列表，并指定单个排序条件
     *
     * @param property  属性
     * @param value     值
     * @param orderName 排序属性
     * @param sortOn    降序或升序
     * @return
     */
    List<T> getListByLike(String property, Object value, String orderName, String sortOn);

    /**
     * 根据多个属性查询指定列表
     *
     * @param properties 属性名称
     * @param values     属性值
     * @return 返回一个列表
     */
    List<T> getListByLike(String[] properties, Object[] values);

    /**
     * 根据多个属性查询指定列表
     *
     * @param properties 属性名称
     * @param values     属性值
     * @param orderNames 排序字段数组
     * @param sortOns    降序或升序数组
     * @return 返回一个列表
     */
    List<T> getListByLike(String[] properties, Object[] values, String[] orderNames, String[] sortOns);

    /**
     * 根据多个属性查询指定列表
     *
     * @param properties 属性名称
     * @param values     属性值
     * @param rangs 排序字段数组
     * @param orderNames 排序字段数组
     * @param sortOns    降序或升序数组
     * @return 返回一个列表
     */
    List<T> getListByLike(String[] properties, Object[] values, List<RangeEntity> rangs, String[] orderNames, String[] sortOns);

    /**
     * 根据多个属性查询列表，并指定多个排序条件
     * @param properties  属性数组
     * @param values 值数组
     * @param orderNames 排序属性数据
     * @param sortOns 升降序数组
     * @return
     */
    List<T> getListByLike(String[] properties,Object[] values,List<RangeEntity> ranges,String[] orderNames,String[] sortOns,int start,int limit);

    /**
     * 根据自定义sql名称查询列表
     *
     * @param sqlName sql名称
     * @param values  参数值
     * @return
     */
    List<T> getListBySqlName(String sqlName, Object[] values);

    /**
     * 根据自定义sql名称查询列表
     *
     * @param sqlName sql名称
     * @param values  命名参数值
     * @return
     */
    List<T> getListByNpSqlName(String sqlName, Map<String, ?> values);

    /**
     * 根据自定义sql查询列表
     *
     * @param sql    sql语句
     * @param values 参数值
     * @return
     */
    List<T> getListBySql(String sql, Object[] values);

    /**
     * 根据自定义sql查询列表
     *
     * @param sql    sql语句
     * @param values 命名参数值
     * @return
     */
    List<T> getListByNpSql(String sql, Map<String, ?> values);

    /**
     * 根据自定义sql名称查询列表
     * @param sqlName sql名称
     * @param values 参数值
     * @return
     */
    <M> List<M> getViewModelList(String sqlName, Class<M> clazz, Object[] values);

    /**
     * 根据自定义sql名称查询列表
     *
     * @param sqlName sql名称
     * @param values  命名参数值
     * @return
     */
    <M> List<M> getViewModelListByNpSqlName(String sqlName, Class<M> clazz, Map<String, ?> values);

    /**
     * 根据自定义sql查询列表
     * @param sql sql
     * @param values 参数值
     * @return
     */
    <M> List<M> getViewModelListBySQL(String sql, Class<M> clazz, Object[] values);

    /**
     * 根据自定义sql查询列表
     * @param sql sql
     * @param values 命名参数值
     * @return
     */
    <M> List<M> getViewModelListByNpSql(String sql, Class<M> clazz, Map<String, ?> values);

    /**
     * 根据单一属性查询分页列表，并指定单个排序条件
     *
     * @param page      分页对象
     * @param property  属性名
     * @param value     值
     * @param orderName 排序属性数据
     * @param sortOn    升降序数组
     * @return
     */
    Page<T> getPage(Page page, String property, Object value, String orderName, String sortOn);

    /**
     * 根据单一属性查询分页列表，并指定多个排序条件
     *
     * @param page       分页对象
     * @param property   属性名
     * @param value      值
     * @param orderNames 排序属性数据
     * @param sortOns    升降序数组
     * @return
     */
    Page<T> getPage(Page page, String property, Object value, String[] orderNames, String[] sortOns);

    /**
     * 根据多个属性查询分页列表，并指定多个排序条件
     *
     * @param page       分页对象
     * @param properties 属性数组
     * @param values     值数组
     * @param orderNames 排序属性数据
     * @param sortOns    升降序数组
     * @return
     */
    Page<T> getPage(Page page, String[] properties, Object[] values, String[] orderNames, String[] sortOns);

    /**
     * 根据多个属性查询分页列表，并指定多个排序条件
     * @param page  分页对象
     * @param properties  属性数组
     * @param values 值数组
     * @param orProperties  or 条件属性数组
     * @param orValues or 条件值数组
     * @param orderNames 排序属性数据
     * @param sortOns 升降序数组
     * @return
     */
    Page<T> queryPage(Page page, String[] properties, Object[] values, String[] orProperties, Object[] orValues, String[] orderNames, String[] sortOns);

    /**
     * 根据多个属性查询分页列表，并指定多个排序条件
     * @param page  分页对象
     * @param properties  属性数组
     * @param values 值数组
     * @param range 范围条件对象
     * @param orderNames 排序属性数据
     * @param sortOns 升降序数组
     * @return
     */
    Page<T> getPage(Page page, String[] properties, Object[] values, RangeEntity range, String[] orderNames, String[] sortOns);

    /**
     * 根据多个属性查询分页列表，并指定多个排序条件
     * @param page  分页对象
     * @param properties  属性数组
     * @param values 值数组
     * @param ranges 范围条件对象
     * @param orderNames 排序属性数据
     * @param sortOns 升降序数组
     * @return
     */
    Page<T> getPage(Page page, String[] properties, Object[] values,List<RangeEntity> ranges, String[] orderNames, String[] sortOns);


    /**
     * 根据多个属性查询分页列表，并指定多个排序条件
     * @param page  分页对象
     * @param properties  属性数组
     * @param values 值数组
     * @param orProperties  or 条件属性数组
     * @param orValues or 条件值数组
     * @param ranges 范围条件对象
     * @param orderNames 排序属性数据
     * @param sortOns 升降序数组
     * @return
     */
    Page<T> getPage(Page page, String[] properties, Object[] values,String[] orProperties, Object[] orValues,List<RangeEntity> ranges, String[] orderNames, String[] sortOns);

    /**
     * 根据自定义sql名称分页查询列表
     * @param page 分页对象
     * @param sqlName sql列表名称
     * @param sqlCountName sql总条数名称
     * @param values 参数值
     * @return
     */
    Page<T> getPageBySqlName(Page page, String sqlName, String sqlCountName, Object[] values);

    /**
     * 根据自定义sql名称分页查询列表
     * @param page 分页对象
     * @param sql 列表sql
     * @param sqlCount 总条数sql
     * @param values 参数值
     * @return
     */
    Page<T> getPageBySql(Page page, String sql, String sqlCount, Object[] values);

    /**
     * 根据自定义sql分页查询列表
     * @param page 分页对象
     * @param sql sql列表
     * @param sqlCount sql总条数
     * @param values 参数值
     * @return
     */
    <M> Page<M> getViewModelPageBySql(Page page, String sql, String sqlCount, Class<M> clazz, Object[] values);

    /**
     * 根据自定义sql名称分页查询列表
     * @param page 分页对象
     * @param sqlName sql列表名称
     * @param sqlCountName sql总条数名称
     * @param values 参数值
     * @return
     */
    <M> Page<M> getViewModelPageBySqlName(Page page, String sqlName, String sqlCountName, Class<M> clazz, Object[] values);

    /**
     * 根据多个属性查询分页列表，并指定多个排序条件
     * @param properties  属性数组
     * @param values 值数组
     * @param ranges 范围条件对象
     * @return
     */
    <M> M getCMSViewModelBySqlName(String sqlName,Class<M> clazz,String[] properties, Object[] values, List<RangeEntity> ranges);

    /**
     * 根据多个属性查询分页列表，并指定多个排序条件
     * @param properties  属性数组
     * @param values 值数组
     * @param ranges 范围条件对象
     * @return
     */
    <M> M getCMSViewModelBySqlName(String sqlName,Class<M> clazz,String[] properties, Object[] values, List<RangeEntity> ranges,Object[] params);

    /**
     * 根据多个属性查询分页列表，并指定多个排序条件
     * @param properties  属性数组
     * @param values 值数组
     * @param ranges 范围条件对象
     * @return
     */
    <M> M getCMSViewModelBySqlName(String sqlName,Class<M> clazz,String[] properties, Object[] values, List<RangeEntity> ranges,Object[] params,boolean paramsAfterCondition);

    /**
     * 根据多个属性查询分页列表，并指定多个排序条件
     * @param page  分页对象
     * @param properties  属性数组
     * @param values 值数组
     * @param ranges 范围条件对象
     * @param orderNames 排序属性数据
     * @param sortOns 升降序数组
     * @return
     */
    <M> Page<M> getCMSViewModelPageBySqlName(Page page,String sqlName,String sumSqlName,Class<M> clazz,String[] properties, Object[] values, List<RangeEntity> ranges,String[] orderNames, String[] sortOns);

    /**
     * 根据多个属性查询分页列表，并指定多个排序条件
     * @param page  分页对象
     * @param properties  属性数组
     * @param values 值数组
     * @param orProperties  or 条件属性数组
     * @param orValues or 条件值数组
     * @param ranges 范围条件对象
     * @param orderNames 排序属性数据
     * @param sortOns 升降序数组
     * @return
     */
    <M> Page<M> getCMSViewModelPageBySqlName(Page page,String sqlName,String sumSqlName,Class<M> clazz,String[] properties, Object[] values,String[] orProperties, Object[] orValues, List<RangeEntity> ranges,String[] orderNames, String[] sortOns);

    /**
     * 根据多个属性查询分页列表，并指定多个排序条件
     * @param page  分页对象
     * @param properties  属性数组
     * @param values 值数组
     * @param ranges 范围条件对象
     * @param orderNames 排序属性数据
     * @param sortOns 升降序数组
     * @param params 其他参数
     * @paramsAfter [condition]参数在params参数后面，还是前面
     * @return
     */
    <M> Page<M> getCMSViewModelPageBySqlName(Page page,String sqlName,String sumSqlName,Class<M> clazz,String[] properties, Object[] values,List<RangeEntity> ranges,String[] orderNames, String[] sortOns,Object[] params,boolean paramsAfterCondition);

    /**
     * 根据多个属性查询列表，并指定多个排序条件
     * @param properties  属性数组
     * @param values 值数组
     * @param orderNames 排序属性数据
     * @param sortOns 升降序数组
     * @return
     */
    <M> List<M> getCMSViewModelListBySqlName(String sqlName,Class<M> clazz,String[] properties,Object[] values,List<RangeEntity> ranges,String[] orderNames,String[] sortOns,Object[] params,boolean paramsAfterCondition);

    /**
     * 根据多个属性查询分页列表，并指定多个排序条件
     * @param properties  属性数组
     * @param values 值数组
     * @param ranges 范围条件对象
     * @param orderNames 排序属性数据
     * @param sortOns 升降序数组
     * @return
     */
    <M> List<M> getCMSViewModelListBySqlName(String sqlName,Class<M> clazz,String[] properties, Object[] values, List<RangeEntity> ranges,String[] orderNames, String[] sortOns);

    /**
     * 根据多个属性查询分页列表，并指定多个排序条件
     * @param properties  属性数组
     * @param values 值数组
     * @param ranges 范围条件对象
     * @return
     */
    <M> List<M> getCMSViewModelListBySqlName(String sqlName,Class<M> clazz,String[] properties, Object[] values, List<RangeEntity> ranges,String[] orderNames, String[] sortOns,Object[] params);

    /**
     * 根据sql name查询Long类型结果
     * @param sqlName
     * @param values
     * @return
     */
    Long getCountBySqlName(String sqlName, Object[] values);

    /**
     * 根据sql name查询泛型结果
     * @param sqlName
     * @param values
     * @param requiredType
     * @return
     * @param <T>
     */
    <T> T getObjectBySqlName(String sqlName, Object[] values, Class<T> requiredType);

    /**
     * 根据sql name查询泛型结果
     * @param sql
     * @param values
     * @return
     */
    <T> T queryObjectBySql(String sql, Object[] values, Class<T> requiredType);

    /**
     * 查询最大的编码
     * @param column
     * @param prefix
     * @param bit
     * @return
     */
    String getMaxCode(String column,String prefix,int bit);

    /**
     * 查询最大的编码
     * @param column
     * @param property
     * @param prefix
     * @param bit
     * @return
     */
    String getMaxCode(String column,String property,String prefix,int bit);


    /**
     * 导出Excel
     * @param exportParams
     * @return
     */
    String exportPage(ExportParams exportParams);

    /**
     * 获得导出文件路径，兼容jar打包方式和war打包方式
     * @param fileName 导出的文件名称
     * @return
     */
    String getExportFilePath(String fileName);

    /**
     * 返回文件下载的路径
     * @param fileName
     * @return
     */
    String getDownFilePath(String fileName);

    /**
     * 返回文件的绝对路径
     * @param path 目录名称
     * @param fileName 文件名称
     * @return
     */
    String getFilePath(String path,String fileName);

    /**
     * 返回文件的绝对路径
     * @param path 文件路径
     * @return
     */
    String getFilePath(String path);
}
